<?php

namespace App\Models\WorkOrder;

use App\Enums\WorkOrder\MissionEnum;
use App\Enums\WorkOrder\OrderEnum;
use App\Models\BaseModel;
use App\Models\Common\ResourcesModel;
use App\Models\FuYou\WorkOrderFuyouInfoModel;
use App\Models\FuYou\WorkOrderFuyouLogModel;
use App\Models\OpenShop\InvestmentPromotion\OpenShopMainProcessModel;
use App\Models\Traits\KfSoftDeletes;
use App\Models\Traits\KfUid;
use App\Service\WorkOrder\WorkOrderBaseService;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\HasOne;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;

class WorkOrderApplyMainModel extends BaseModel
{
    use KfSoftDeletes;
    use KfUid;

    protected $table = 'work_order_apply_main';

    const MERCHANT_CONFIRM_FINISH_TYPE_SYSTEM   = 1;
    const MERCHANT_CONFIRM_FINISH_TYPE_MERCHANT = 2;

    const MERCHANT_CONFIRM_FINISH_STATUS_FINISH = 1;

    const SOURCE_TYPE_0 = 0;
    const SOURCE_TYPE_1 = 1;
    const SOURCE_TYPE_2 = 2;
    const SOURCE_TYPE_3 = 3;

    const SOURCE_TYPE_TEXT = [
        self::SOURCE_TYPE_0 => "夸父商家",
        self::SOURCE_TYPE_1 => "企业微信",
        self::SOURCE_TYPE_2 => "400客服",
        self::SOURCE_TYPE_3 => "其他渠道",
    ];

    const SOURCE_TYPE_ARRAY = [
        self::SOURCE_TYPE_0,
        self::SOURCE_TYPE_1,
        self::SOURCE_TYPE_2,
        self::SOURCE_TYPE_3,
    ];

    // 新增的问题类型，仅限非夸父商家渠道反馈的问题
    const SOURCE_TYPE_ARRAY_CUSTOMER = [
        self::SOURCE_TYPE_1,
        self::SOURCE_TYPE_2,
        self::SOURCE_TYPE_3,
    ];

    protected $fillable = [
        'workOrderNo',
        'shopId',
        'problemPid',
        'problemChildId',
        'problemDesc',
        'status',
        'step',
        'childStep',
        'priority',
        'completeTime',
        'extra',
        'createdByUid',
        'updatedByUid',
        'createdAt',
        'updatedAt',
        'isDeleted',
        'sourceType',
        'merchantConfirmFinishType',
        'merchantConfirmFinishTime',
        'merchantConfirmFinishStatus'
    ];


    /**
     * @param int $id
     * @return Builder|Model|object|null
     */
    public static function getDetailById(int $id)
    {
        return self::query()->where("id", $id)->first();
    }


    /**
     * @param string $workOrderNo
     * @param bool $isDel
     * @return Builder|Model|object|null
     */
    public static function getDetailByWorkOrderNo(string $workOrderNo, bool $isDel = false)
    {
        return self::query()->with(
            [
                'fuyouInfoRel' => function ($query) {
                    $query->orderByDesc('id');
                },
                'contentRel',
                'fuyouLogRel',
                'openShopMainProcessRel' => function ($q) {
                    $q->with([
                        'signOrderRel.contractRel',
                        'openShopSiteLocationRel'
                    ]);
                }
            ]
        )
            ->where("workOrderNo", $workOrderNo)
            ->when(
                $isDel, function ($query) {
                $query->withoutGlobalScope('isDel');
            }
            )->first();
    }

    /**
     * 创建或获取门店申请
     *
     * @param int $shopId
     * @param int $problemPid
     * @param int $problemChildId
     * @param int $uid
     * @return Builder|Model
     */
    public static function getOrCreateApplyMain(int $shopId, int $problemPid, int $problemChildId, int $uid)
    {
        return self::query()->firstOrCreate(
            [
                "shopId"         => $shopId,
                "problemPid"     => $problemPid,
                "problemChildId" => $problemChildId,
            ],
            [
                "workOrderNo"    => WorkOrderBaseService::createWorkOrderNo($problemPid, $problemChildId),
                "step"           => MissionEnum::STEP_1,
                "shopId"         => $shopId,
                "problemPid"     => $problemPid,
                "problemChildId" => $problemChildId,
                "status"         => OrderEnum::MAIN_STATUS_ING,
                "isDeleted"      => 0,
                "createdByUid"   => $uid,
                "updatedAt"      => time(),
                "createdAt"      => time()
            ]
        );
    }

    public function openShopMainProcessRel(): HasOne
    {
        return $this->hasOne(OpenShopMainProcessModel::class, 'shopId', 'shopId');
    }

    /**
     * @return HasOne
     */
    public function contentRel(): HasOne
    {
        return $this->hasOne(WorkOrderApplyContentModel::class, 'workOrderNo', 'workOrderNo');
    }

    public function managerRel(): HasMany
    {
        return $this->hasMany(WorkOrderApplyManagerModel::class, 'workOrderNo', 'workOrderNo');
    }

    public function getProblemPidTextAttribute(): string
    {
        return OrderEnum::PROBLEM_PID_TEXT[$this->problemPid] ?? '-';
    }

    public function getProblemChildIdTextAttribute(): string
    {
        $text = '';

        switch ($this->problemPid) {
            case OrderEnum::PROBLEM_PID_1:
                $text = OrderEnum::PROBLEM_PID_1_CHILDREN_MAPPING[$this->problemChildId] ?? '--';
                break;
            case OrderEnum::PROBLEM_PID_2:
                $text = OrderEnum::PROBLEM_PID_2_CHILDREN_MAPPING[$this->problemChildId] ?? '--';
                break;
            case OrderEnum::PROBLEM_PID_4:
                $text = OrderEnum::PROBLEM_PID_4_CHILDREN_MAPPING[$this->problemChildId] ?? '--';
                break;
            case OrderEnum::PROBLEM_PID_5:
                $text = OrderEnum::FUNCTION_OPEN[$this->problemChildId] ?? '--';
                break;
            case OrderEnum::PROBLEM_PID_6:
                $text = OrderEnum::PROBLEM_PID_6_CHILDREN_MAPPING[$this->problemChildId] ?? '--';
                break;
            case OrderEnum::PROBLEM_PID_7:
                $text = OrderEnum::PROBLEM_PID_7_CHILDREN_MAPPING[$this->problemChildId] ?? '--';
                break;
            case OrderEnum::PROBLEM_PID_8:
                $text = OrderEnum::PROBLEM_PID_8_CHILDREN_MAPPING[$this->problemChildId] ?? '--';
                break;
            case OrderEnum::PROBLEM_PID_9:
                $text = OrderEnum::PROBLEM_PID_9_CHILDREN_MAPPING[$this->problemChildId] ?? '--';
                break;
            case OrderEnum::PROBLEM_PID_10:
                $text = OrderEnum::PROBLEM_PID_10_CHILDREN_MAPPING[$this->problemChildId] ?? '--';
                break;
        }

        return $text;
    }

    public function getProblemChildIdTextShortAttribute(): string
    {
        return OrderEnum::PROBLEM_PID_TEXT_SHORT[$this->problemPid] ?? '';
    }

    public function getStepTextAttribute(): string
    {
        return MissionEnum::STEP_TEXT[$this->step] ?? '';
    }

    public function getPriorityTextAttribute(): string
    {
        return OrderEnum::PRIORITY_TEXT[$this->priority] ?? '-';
    }

    public function getExtraArrAttribute(): array
    {
        return (array)json_decode($this->extra, true);
    }

    /**
     * 更新step
     * @param string $workOrderNo
     * @param int $step
     * @return int
     */
    public static function saveStep(string $workOrderNo, int $step): bool
    {
        $main = self::query()->where('workOrderNo', $workOrderNo)->first();

        if (in_array($step, [MissionEnum::STEP_99, MissionEnum::STEP_100])) {
            $main->completeTime = time();

            if ($step == MissionEnum::STEP_99) {
                $main->status = OrderEnum::MAIN_STATUS_FINISH;
            }

            if ($step == MissionEnum::STEP_100) {
                $main->status = OrderEnum::MAIN_STATUS_CLOSE;
            }
        }

        $main->step = $step;

        return $main->save();
    }

    /**
     * 是否是外卖开通
     *
     * @return bool
     */
    public function isFunctionWaiMaiOpen(): bool
    {
        if ($this->problemPid == OrderEnum::PROBLEM_PID_5 && in_array($this->problemChildId,
                [
                    OrderEnum::PROBLEM_PID_5_CHILDREN_101,
                    OrderEnum::PROBLEM_PID_5_CHILDREN_102
                ])) {
            return true;
        }
        return false;
    }

    /**
     * 关联任务
     *
     * @return HasMany
     */
    public function missionsRel(): HasMany
    {
        return $this->hasMany(WorkOrderMissionModel::class, "workOrderNo", "workOrderNo");
    }

    /**
     * @param string $workOrderNo
     * @return Builder|Model|object|null
     */
    public static function getApplyStayMissionByWorkOrderNo(string $workOrderNo)
    {
        return self::query()
                   ->where("workOrderNo", $workOrderNo)
                   ->with([
                       "missionsRel" => function ($query) {
                           $query->where("missionStatus", MissionEnum::MISSION_STATUS_0);
                       }
                   ])->first();
    }


    /**
     * 获取申请状态
     *
     * @param int $step
     * @return int
     */
    public static function applyMainStatus(int $step): int
    {
        if ($step <= MissionEnum::STEP_1) {
            return OrderEnum::MAIN_STATUS_CLOSE;
        } else {
            if ($step < MissionEnum::STEP_99) {
                return OrderEnum::MAIN_STATUS_ING;
            } else {
                return OrderEnum::MAIN_STATUS_FINISH;
            }
        }
    }

    /**
     * 修改二级阶段
     * @param int $childStep
     * @return $this
     */
    public function saveChildStep(int $childStep): self
    {
        $this->childStep = $childStep;
        $this->save();

        return $this;
    }

    public function getMainStatusTextAttribute(): string
    {
        if ($this->childStep == MissionEnum::CHILD_STEP_1) {
            return '待修改';
        }

        return OrderEnum::MAIN_STATUS_TEXT[$this->status] ?? '-';
    }

    /**
     * 关联富友信息
     * @return HasOne
     */
    public function fuyouInfoRel(): HasOne
    {
        return $this->hasOne(WorkOrderFuyouInfoModel::class, 'workOrderNo', 'workOrderNo');
    }

    /**
     * 关联富友审核记录
     * @return HasMany
     */
    public function fuyouLogRel(): HasMany
    {
        return $this->hasMany(WorkOrderFuyouLogModel::class, "workOrderNo", "workOrderNo");
    }

    /**
     * 关联资源表
     * @return HasMany
     */
    public function resourcesRel(): HasMany
    {
        return $this->hasMany(ResourcesModel::class, 'businessId', 'id')
                    ->where('module', ResourcesModel::MODULE_TYPE_WORK_ORDER)
                    ->where('business', ResourcesModel::BUSINESS_WORK_ORDER_FUNCTION_OPEN)
                    ->whereIn('name', ['businessLicenseImg', 'foodBusinessLicenseImg']);
    }

}
